<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>无标题文档</title>
<script src="./js/jquery-1.9.1.js" type="text/javascript"></script>
<script src="./js/raphael.js" type="text/javascript"></script>
<style type="text/css">
#holder
        {
            top: 0px;
            left: 0px;
            right: 0px;
            bottom: 0px;
            position: absolute;
            z-index: 999;
        }
        test
        {
            position: absolute;
            width: 80px;
            height: 30px;
            top: 0px;
            z-index: 0;
        }
</style>
<script type="text/javascript">
//随着节点位置的改变动态改变箭头
        Raphael.fn.drawArr = function (obj) {
            var point = getStartEnd(obj.obj1, obj.obj2);
            var path1 = getArr(point.start.x, point.start.y, point.end.x, point.end.y, 8);
            if (obj.arrPath) {
                obj.arrPath.attr({ path: path1 });
            } else {
                obj.arrPath = this.path(path1);
            }
            return obj;
        };
        function getStartEnd(obj1, obj2) {
            var bb1 = obj1.getBBox(),
                bb2 = obj2.getBBox();
            var p = [
                    { x: bb1.x + bb1.width / 2, y: bb1.y - 1 },
                    { x: bb1.x + bb1.width / 2, y: bb1.y + bb1.height + 1 },
                    { x: bb1.x - 1, y: bb1.y + bb1.height / 2 },
                    { x: bb1.x + bb1.width + 1, y: bb1.y + bb1.height / 2 },
                    { x: bb2.x + bb2.width / 2, y: bb2.y - 1 },
                    { x: bb2.x + bb2.width / 2, y: bb2.y + bb2.height + 1 },
                    { x: bb2.x - 1, y: bb2.y + bb2.height / 2 },
                    { x: bb2.x + bb2.width + 1, y: bb2.y + bb2.height / 2 }
                ];
            var d = {}, dis = [];
            for (var i = 0; i < 4; i++) {
                for (var j = 4; j < 8; j++) {
                    var dx = Math.abs(p[i].x - p[j].x),
                        dy = Math.abs(p[i].y - p[j].y);
                    if (
                         (i == j - 4) ||
                         (((i != 3 && j != 6) || p[i].x < p[j].x) &&
                         ((i != 2 && j != 7) || p[i].x > p[j].x) &&
                         ((i != 0 && j != 5) || p[i].y > p[j].y) &&
                         ((i != 1 && j != 4) || p[i].y < p[j].y))
                       ) {
                        dis.push(dx + dy);
                        d[dis[dis.length - 1]] = [i, j];
                    }
                }
            }
            if (dis.length == 0) {
                var res = [0, 4];
            } else {
                res = d[Math.min.apply(Math, dis)];
            }
            var result = {};
            result.start = {};
            result.end = {};
            result.start.x = p[res[0]].x;
            result.start.y = p[res[0]].y;
            result.end.x = p[res[1]].x;
            result.end.y = p[res[1]].y;
            return result;
        }
	 //获取组成箭头的三条线段的路径
        function getArr(x1, y1, x2, y2, size) {
            var angle = Raphael.angle(x1, y1, x2, y2);//得到两点之间的角度
            var a45 = Raphael.rad(angle - 45);//角度转换成弧度
            var a45m = Raphael.rad(angle + 45);
            var x2a = x2 + Math.cos(a45) * size;
            var y2a = y2 + Math.sin(a45) * size;
            var x2b = x2 + Math.cos(a45m) * size;
            var y2b = y2 + Math.sin(a45m) * size;
            var result = ["M", x1, y1, "L", x2, y2, "L", x2a, y2a, "M", x2, y2, "L", x2b, y2b];
            return result;
        }
 
	 $(function () {
            //用来存储节点的顺序
            var connections = [];
            //拖动节点开始时的事件
            var dragger = function () {
                this.ox = this.attr("x");
                this.oy = this.attr("y");
                this.animate({ "fill-opacity": .2 }, 500);
            };
            //拖动事件
            var move = function (dx, dy) {
                var att = { x: this.ox + dx, y: this.oy + dy };
                this.attr(att);
                $("#test" + this.id).offset({ top: this.oy + dy + 10, left: this.ox + dx + 10 });
                for (var i = connections.length; i--; ) {
                    r.drawArr(connections[i]);
                }
            };
            //拖动结束后的事件
            var up = function () {
                this.animate({ "fill-opacity": 0 }, 500);
            };
            //创建绘图对象
            var r = Raphael("holder", $(window).width(), $(window).height());
            //绘制节点
            var shapes = [
                        r.rect(190, 100, 60, 40, 4),
                        r.rect(290, 80, 60, 40, 4),
                        r.rect(290, 180, 60, 40, 4),
                        r.rect(450, 100, 60, 40, 4)
                     ];
            //定位节点上的文字
            $("#test1").offset({ top: 100 + 10, left: 190 + 10 });
            $("#test2").offset({ top: 80 + 10, left: 290 + 10 });
            $("#test3").offset({ top: 180 + 10, left: 290 + 10 });
            $("#test4").offset({ top: 100 + 10, left: 450 + 10 });
            //为节点添加样式和事件，并且绘制节点之间的箭头
            for (var i = 0, ii = shapes.length; i < ii; i++) {
                var color = Raphael.getColor();
                shapes[i].attr({ fill: color, stroke: color, "fill-opacity": 0, "stroke-width": 2, cursor: "move" });
                shapes[i].id = i + 1;
                shapes[i].drag(move, dragger, up);
                shapes[i].dblclick(function () { alert(this.id) })
            }
            //存储节点间的顺序
            connections.push(r.drawArr({ obj1: shapes[0], obj2: shapes[1] }));
            connections.push(r.drawArr({ obj1: shapes[1], obj2: shapes[2] }));
            connections.push(r.drawArr({ obj1: shapes[2], obj2: shapes[3] }));
        });
</script>
</head>

<body>
<div id="holder">
    </div>
    <div id="test1" class="test">
        测试1</div>
    <div id="test2" class="test">
        测试2</div>
    <div id="test3" class="test">
        测试3</div>
    <div id="test4" class="test">
        测试4</div>

</body>
</html>
